﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using HenIT.BizTalk;
using btom = Microsoft.BizTalk.ExplorerOM;

namespace HenIT.BizTalk
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private string lastSaveFile = "";

        private void lblBTSTask_Click(object sender, EventArgs e)
        {
            openFileDialogBTSTaskExec.FileName = Properties.Settings.Default.BTSTask;
            if (openFileDialogBTSTaskExec.ShowDialog() == DialogResult.OK)
            {
                Properties.Settings.Default.BTSTask = openFileDialogBTSTaskExec.FileName;
                Properties.Settings.Default.Save();
                lblBTSTask.ForeColor = SystemColors.ControlText;
                cmdImport.Enabled = true;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!File.Exists(Properties.Settings.Default.BTSTask))
            {
                MessageBox.Show("BTSTask.exe not found! Please verify location of executable and update config file.", "BTSTask", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                lblBTSTask.ForeColor = Color.Red;
                cmdImport.Enabled = false;
            }

            lblBTSTask.Text = Properties.Settings.Default.BTSTask;
            if (Properties.Settings.Default.LastMgmtServer == null || Properties.Settings.Default.LastMgmtServer.Length == 0)
                Properties.Settings.Default.LastMgmtServer = BizTalkUtils.GetCurrentBizTalkSqlServer();
            txtMgmtServer.Text = Properties.Settings.Default.LastMgmtServer;
            if (Properties.Settings.Default.LastMgmtDb == null || Properties.Settings.Default.LastMgmtDb.Length == 0)
                Properties.Settings.Default.LastMgmtDb = BizTalkUtils.GetCurrentBizTalkMgmtDb();
            txtMgmtDb.Text = Properties.Settings.Default.LastMgmtDb;
        }

        private void cmdSelectMSI_Click(object sender, EventArgs e)
        {
            openFileDialogMSI.InitialDirectory = Properties.Settings.Default.LastMSIDirectory;
            if (openFileDialogMSI.ShowDialog() == DialogResult.OK)
            {
                foreach (string fileName in openFileDialogMSI.FileNames)
                {
                    ListViewItem lvi = new ListViewItem();
                    lvi.Text = Path.GetFileNameWithoutExtension(fileName);
                    lvi.SubItems.Add(fileName);
                    lvi.SubItems.Add(txtDefaultEnv.Text);
                    lvi.SubItems.Add("");
                    lvwMSIs.Items.Add(lvi);
                }
                Properties.Settings.Default.LastMSIDirectory = Path.GetDirectoryName(openFileDialogMSI.FileNames[0]);
                Properties.Settings.Default.Save();
            }
        }

        private void cmdSet_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwMSIs.SelectedItems)
            {
                if (txtEnvironment.Text.Length > 0)
                    lvi.SubItems[2].Text = txtEnvironment.Text;
            }
        }

        private void clearApplicationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwMSIs.SelectedItems)
            {
                lvi.SubItems[2].Text = "";
            }
        }

        private void cmdImport_Click(object sender, EventArgs e)
        {
            string batchCmnd = "";
            StringBuilder sb = new StringBuilder();
            if (txtBatchFile.Text.Length == 0)
            {
                MessageBox.Show("Please specify an output batchfile!", "Batch file", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            else
            {
                try
                {
                    foreach (ListViewItem lvi in lvwMSIs.Items)
                    {
                        if (chkUninstall.Checked)
                        {
                            sb.Append("\"" + Properties.Settings.Default.BTSTask + "\" UninstallApp -ApplicationName:\"" + lvi.Text + "\"\r\n");
                        }
                        if (chkRemoveApp.Checked)
                        {
                            sb.Append("\"" + Properties.Settings.Default.BTSTask + "\" RemoveApp -ApplicationName:\"" + lvi.Text + "\"\r\n");
                        }

                        sb.Append("\"" + Properties.Settings.Default.BTSTask + "\" importapp " +
                            "-ApplicationName:\"" + lvi.Text + "\" " +
                            "-Package:\"" + lvi.SubItems[1].Text + "\" " +
                            (chkOverwrite.Checked ? "-Overwrite " : "").ToString() +
                            (lvi.SubItems[2].Text.Length > 0 ? "-Environment:\"" + lvi.SubItems[2].Text + "\" " : "").ToString() +
                            "-Server:" + txtMgmtServer.Text + " " +
                            "-Database:" + txtMgmtDb.Text + "\r\n");

                        if (lvi.SubItems[3].Text.Length > 0)
                        {
                            sb.Append("\"" + Properties.Settings.Default.BTSTask + "\" ImportBindings " +
                            "-Source:\"" + lvi.SubItems[3].Text + "\" " +
                            "-ApplicationName:\"" + lvi.Text + "\" " +
                            "-Server:" + txtMgmtServer.Text + " " +
                            "-Database:" + txtMgmtDb.Text + "\r\n");
                        }

                        if (chkRunMSI.Checked)
                        {
                            sb.Append("msiexec /i " +
                            "\"" + lvi.SubItems[1].Text + "\" /passive" + "\r\n");
                        }
                    }

                    if (chkPause.Checked)
                        sb.Append("pause");
                    batchCmnd = sb.ToString();

                    StreamWriter output = File.CreateText(txtBatchFile.Text);
                    output.Write(batchCmnd);
                    output.Flush();
                    output.Close();
                    if (chkRunBatch.Checked)
                        System.Diagnostics.Process.Start(txtBatchFile.Text);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            saveFileDialogCMD.FileName = txtBatchFile.Text;
            if (saveFileDialogCMD.ShowDialog() == DialogResult.OK)
            {
                txtBatchFile.Text = saveFileDialogCMD.FileName;
            }
        }

        private void removeMSIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwMSIs.SelectedItems)
            {
                lvwMSIs.Items.Remove(lvi);
            }
        }

        private void lvwMSIs_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                removeMSIToolStripMenuItem_Click(sender, e);
            }
        }

        private void lvwMSIs_DoubleClick(object sender, EventArgs e)
        {
            if (lvwMSIs.SelectedItems.Count == 1)
            {
                txtAppName.Text = lvwMSIs.SelectedItems[0].Text;
                txtEnvironment.Text = lvwMSIs.SelectedItems[0].SubItems[2].Text;
            }
        }

        private void addBindingFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lvwMSIs.SelectedItems.Count == 1)
            {
                openFileDialogBinding.FileName = lvwMSIs.SelectedItems[0].SubItems[3].Text;
                if (openFileDialogBinding.ShowDialog() == DialogResult.OK)
                {
                    lvwMSIs.SelectedItems[0].SubItems[3].Text = openFileDialogBinding.FileName;
                }
            }
        }

        private void clearBindingFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwMSIs.SelectedItems)
            {
                lvi.SubItems[3].Text = "";
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void newSetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            lvwMSIs.Items.Clear();
            lastSaveFile = "";
        }

        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialogBAL.FileName = lastSaveFile;
            if (openFileDialogBAL.ShowDialog() == DialogResult.OK)
            {
                lastSaveFile = openFileDialogBAL.FileName;
                OpenBal();
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lastSaveFile.Length == 0)
                saveAsToolStripMenuItem_Click(sender, e);
            else
                SaveBAL();
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialogBAL.FileName = lastSaveFile;
            if (saveFileDialogBAL.ShowDialog() == DialogResult.OK) 
            {
                lastSaveFile = saveFileDialogBAL.FileName;
                SaveBAL();
            }
        }
        private bool OpenBal()
        {
            bool success = false;
            try
            {
                lvwMSIs.Items.Clear();
                XmlDocument config = new XmlDocument();
                config.Load(lastSaveFile);
                XmlNode applicationListNode = config.SelectSingleNode("config/applicationList");
                txtMgmtServer.Text = N(applicationListNode.Attributes.GetNamedItem("mgmtSvr").Value);
                txtMgmtDb.Text = N(applicationListNode.Attributes.GetNamedItem("mgmtDb").Value);
                chkOverwrite.Checked = bool.Parse(ReadAttribute(applicationListNode, "overwrite", "False"));
                chkRunMSI.Checked = bool.Parse(ReadAttribute(applicationListNode, "runMSI", "False"));
                chkPause.Checked = bool.Parse(ReadAttribute(applicationListNode,"pause", "False"));
                chkRunBatch.Checked = bool.Parse(ReadAttribute(applicationListNode, "runBatch", "True"));
                txtDefaultEnv.Text = ReadAttribute(applicationListNode,"defaultEnv");
                txtBatchFile.Text = ReadAttribute(applicationListNode,"batchFile"); 

                foreach (XmlNode appNode in applicationListNode.SelectNodes("application"))
                {
                    ListViewItem lvi = new ListViewItem();
                    lvi.Text = ReadAttribute(appNode,"name");
                    lvi.SubItems.Add(ReadAttribute(appNode,"msi"));
                    lvi.SubItems.Add(ReadAttribute(appNode,"env"));
                    lvi.SubItems.Add(ReadAttribute(appNode,"binding"));
                    lvwMSIs.Items.Add(lvi);
                }
                success = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return success;
        }
        private bool SaveBAL()
        {
            bool success = false;
            try
            {
                XmlDocument config = new XmlDocument();
                config.LoadXml("<config><applicationList></applicationList></config>");
                XmlNode applicationListNode = config.SelectSingleNode("config/applicationList");

                AddAttribute(applicationListNode, "mgmtSvr", txtMgmtServer.Text);
                AddAttribute(applicationListNode, "mgmtDb", txtMgmtDb.Text);
                AddAttribute(applicationListNode, "overwrite", chkOverwrite.Checked.ToString());
                AddAttribute(applicationListNode, "runMSI", chkRunMSI.Checked.ToString());
                AddAttribute(applicationListNode, "pause", chkPause.Checked.ToString());
                AddAttribute(applicationListNode, "runBatch", chkRunBatch.Checked.ToString());
                AddAttribute(applicationListNode, "defaultEnv", txtDefaultEnv.Text);
                AddAttribute(applicationListNode, "batchFile", txtBatchFile.Text);

                foreach (ListViewItem lvi in lvwMSIs.Items)
                {
                    XmlNode applicationXmlNode = config.CreateElement("application");
                    //Application name
                    AddAttribute(applicationXmlNode, "name", lvi.Text);
                    //MSI
                    AddAttribute(applicationXmlNode, "msi", lvi.SubItems[1].Text);
                    //Env
                    AddAttribute(applicationXmlNode, "env", lvi.SubItems[2].Text);
                    //Binding
                    AddAttribute(applicationXmlNode, "binding", lvi.SubItems[3].Text);

                    applicationListNode.AppendChild(applicationXmlNode);
                }

                config.Save(lastSaveFile);

                success = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return success;
        }

        private void AddAttribute(XmlNode node, string attributeName, string value)
        {
            XmlAttribute newattr = node.OwnerDocument.CreateAttribute(attributeName);
            newattr.Value = value;
            node.Attributes.Append(newattr);
        }

        private string ReadAttribute(XmlNode node, string attributeName, string defaultValue)
        {
            string value = defaultValue;
            if (node.Attributes.GetNamedItem(attributeName) != null)
            {
                value = node.Attributes.GetNamedItem(attributeName).Value;
            }
            return value;
        }
        private string ReadAttribute(XmlNode node, string attributeName)
        {
            return ReadAttribute(node, attributeName, "");
        }
        private string N(object anyVal)
        {
            if (anyVal != null)
            {
                return anyVal.ToString();
            }
            else
            {
                return "";
            }
        }

        private void cmdTestConnection_Click(object sender, EventArgs e)
        {

            using (btom.BtsCatalogExplorer catalog = new Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer())
            {
                catalog.ConnectionString = "Server=" + txtMgmtServer.Text + ";Database=" + txtMgmtDb.Text + ";Trusted_Connection=True;";
                try
                {
                    MessageBox.Show("BizTalk group name: " + catalog.GroupName, "Testing", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Testing", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
    }
}
